﻿//////////////////////////////////////////////////////////////////////////////
//
// Copyright © 1998-2024 Glodon Company Limited.
//
// Licensed under the MIT License
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the “Software”),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
//////////////////////////////////////////////////////////////////////////////
#pragma once

// std headers

// qt headers
#include <QWidget>
#include <QTimer>

// custom headers
#include "GmepGcsMainUI.h"


class QLabel;
class QFont;

namespace gmepgcs
{
    class GCS_MAINUI_EXPORTS BnufBulletin : public QWidget
    {
        Q_OBJECT

    public:
        enum class BulletinIcon : int32_t
        {
            NoIcon = 0,
            Info = 1,
            Warning  =2,
            Error = 3,
            Waiting = 4,
            Success = 5,
            Close = 6
        };
        Q_ENUM(BulletinIcon)

    private:
        explicit BnufBulletin(QWidget *parent = nullptr);
        BnufBulletin(const BnufBulletin &) = default;
        BnufBulletin &operator=(const BnufBulletin &) = default;
        virtual ~BnufBulletin();

    public:
        virtual bool eventFilter(QObject *watched, QEvent *event) override;
                
    public:
        static void SetDock(QWidget *dock);
        static void SingleShot(const std::wstring &message, const BulletinIcon &icon, const int32_t &duration = 3000, QWidget *parent = nullptr);

        template<typename Func>
        static void SingleShot(const std::wstring &message, const BulletinIcon &icon, const int32_t &duration = 3000, QWidget *parent = nullptr, Func onFinish = [](){});

        template<typename Func>
        static void SingleShooting(const std::wstring &message, const BulletinIcon &icon, Func finsihSetter,  QWidget *parent = nullptr);
        
    public:
        BnufBulletin *ConfigMessage(const std::wstring &message);
        BnufBulletin *ConfigIcon(const BulletinIcon &icon);
        BnufBulletin *ConfigProgress(const int &current, const int &total);

        void CloseLater(const int32_t &delay = 3000);

    signals:
        void WillClose();

    protected:
        virtual void paintEvent(QPaintEvent *event) override;
        virtual void closeEvent(QCloseEvent *event) override;

    private:
        static BnufBulletin *Create(QWidget *parent);
        void Init();
        BnufBulletin *ConfigGeometry();
        void StartExit();

    private:
        static QWidget *s_pWgtDock;
        QLabel *m_pLblIcon;
        QLabel *m_pLblText;
        QLabel *m_pLblProgress;

    private:
        QFont m_textFont;
        int m_progressTotal;
        int m_progressCurrent;
    };
    

    template<typename Func>
    inline void BnufBulletin::SingleShot(const std::wstring & message, const BulletinIcon & icon, const int32_t &duration, QWidget * parent, Func onFinish)
    {
        auto bulletin = BnufBulletin::Create(parent);
        if (!bulletin)
        {
            return;
        }
        
        connect(bulletin, &BnufBulletin::WillClose, [=]() {onFinish(); });
        DBG_WARN_AND_RETURN_VOID_UNLESS(bulletin->ConfigIcon(icon), L"bulletin->ConfigIcon(icon)为空", L"GMEP", L"2024-01-30");
        DBG_WARN_AND_RETURN_VOID_UNLESS(bulletin->ConfigIcon(icon)->ConfigMessage(message), L"bulletin->ConfigIcon(icon)->ConfigMessage(message)为空", L"GMEP", L"2024-01-30");
        bulletin->ConfigIcon(icon)->ConfigMessage(message)->show();
        
        QTimer::singleShot(duration < 0 ? 0 : duration, [=] {bulletin->StartExit(); });
    }

    template<typename Func>
    inline void BnufBulletin::SingleShooting(const std::wstring &message, const BulletinIcon &icon, Func finishSetter, QWidget *parent)
    {
        auto bulletin = BnufBulletin::Create(parent);
        if (!bulletin)
        {
            return;
        }

        DBG_WARN_AND_RETURN_VOID_UNLESS(bulletin->ConfigIcon(icon), L"bulletin->ConfigIcon(icon)为空", L"GMEP", L"2024-01-30");
        DBG_WARN_AND_RETURN_VOID_UNLESS(bulletin->ConfigIcon(icon)->ConfigMessage(message), L"bulletin->ConfigIcon(icon)->ConfigMessage(message)为空", L"GMEP", L"2024-01-30");
        bulletin->ConfigIcon(icon)->ConfigMessage(message)->show();
        finishSetter(bulletin);
    }
}